package idv.arthur.svn;

import idv.arthur.jenkins.JobDepStruc;
import idv.arthur.structures.B1I1;
import idv.arthur.widgets.CommitMediator;
import idv.arthur.widgets.Widgets;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import org.tmatesoft.svn.core.SVNCommitInfo;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNProperties;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.io.ISVNEditor;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.io.diff.SVNDeltaGenerator;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

public class CreateTest {

	public static void main(String[] args) throws Exception {

		
		String strSQL;
		String res = null;
		Connection conn = null;
		PreparedStatement ps = null;
		PreparedStatement ps2 = null;
		ResultSet rs = null;
		ResultSet rs2 = null;
		final Widgets wid = new Widgets();
		//SVN抓取檔案要用
				InputStream input = null;
				ByteArrayOutputStream baos = null;

				SVNRepository cmOLrepo = null;	//SVN CM OL的Repo
				SVNRepository cmOLrepoCHK = null;	//SVN CM OL的Repo	為了做檢查用
				SVNRepository apMRrepo = null;	//SVN AP MR的Repo
				SVNRepository apOLrepo = null;	//SVN AP OL的Repo
				SVNRepository apRepo = null;	//SVN AP 的repo
		final int chkInId = 395;
		//將檔案從 SVN AP 寫入 SVN CM OL
		
		ISVNEditor editor = null;
		SVNCommitInfo info = null;
		final SVNProperties fileProperties = new SVNProperties();
		baos = new ByteArrayOutputStream();
		final String subsysId = "BL";
		/*	此區開始建立SVN連線	*/
		final ArrayList<String> connCMsvnOLinfo = wid.getSVN4SubsysConnInfo(subsysId, 2);	//SVN CM OL的連線資訊
		final ArrayList<String> connAPsvnMRinfo = wid.getSVN4SubsysConnInfo(subsysId, 3);	//SVN AP MR的連線資訊
		final ArrayList<String> connAPsvnOLinfo = wid.getSVN4SubsysConnInfo(subsysId, 4);	//SVN AP OL的連線資訊
		
		ISVNAuthenticationManager authManager = null;
		apMRrepo = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(connAPsvnMRinfo.get(0)));	//連線到SVN AP MR 的repo
		apOLrepo = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(connAPsvnOLinfo.get(0)));	//連線到SVN AP OL 的repo
        authManager = SVNWCUtil.createDefaultAuthenticationManager(connAPsvnMRinfo.get(1), connAPsvnMRinfo.get(2));
        apMRrepo.setAuthenticationManager(authManager);
        authManager = SVNWCUtil.createDefaultAuthenticationManager(connAPsvnOLinfo.get(1), connAPsvnOLinfo.get(2));
        apOLrepo.setAuthenticationManager(authManager);
        
        final SVNDeltaGenerator deltaGenerator = new SVNDeltaGenerator();
		
        try {
        	conn = wid.getConn();
        	//開始查詢有那些要處理的檔案
            strSQL = "SELECT modId FROM chkinmod WHERE chkInMainId=?";
            ps = conn.prepareStatement(strSQL);
            ps.setInt(1, chkInId);
            rs = ps.executeQuery();
            cmOLrepo = SVNRepositoryFactory.create(SVNURL.parseURIEncoded( connCMsvnOLinfo.get(0) ));	//連線到SVN CM OL 的repo
        	cmOLrepoCHK = SVNRepositoryFactory.create(SVNURL.parseURIEncoded( connCMsvnOLinfo.get(0) ));	//連線到SVN CM OL 的repo
        	authManager = SVNWCUtil.createDefaultAuthenticationManager(connCMsvnOLinfo.get(1), connCMsvnOLinfo.get(2));
    		cmOLrepo.setAuthenticationManager(authManager);
    		cmOLrepoCHK.setAuthenticationManager(authManager);
    		
            while ( rs.next() ) {	//此while loop即要處理的模組
            	editor = cmOLrepo.getCommitEditor(null, new CommitMediator() );
            	editor.openRoot(-1);
            	final String modId = rs.getString("modId");
            	strSQL = "SELECT isMR,fileName,relativePath,fileVer FROM chkinmoddetail WHERE chkInMainId=? AND modId=?";
            	ps2 = conn.prepareStatement(strSQL);
    	        ps2.setInt(1, chkInId);
    	        ps2.setString(2, modId);
    	        rs2 = ps2.executeQuery();
    	        while ( rs2.next() ) {	//模組下要處理的檔案
                	try {	//若能夠打開該路徑的資料夾，便是該夾存在，否則便進入catch來創建該資料夾
                		System.out.println("嘗試新增模組夾"+modId);
                		editor.addDir(modId,null,-1);
                	} catch ( Exception e) {
                		System.out.println("無法新增，嘗試打開模組夾："+modId);
                		//editor.openDir(modId,-1);	//不能OPEN程式才會正確跑!!
                	}
    	        	final boolean isMR = "t".equalsIgnoreCase(rs2.getString("isMR"));
    	        	final long fileVer = rs2.getInt("fileVer");
    	        	String relativePath = rs2.getString("relativePath");
    	        	final String fileName = rs2.getString("fileName");
    	        	final String depFilePath = modId+"/"+relativePath+fileName;	//欲部署的檔案在那裡，此時的relativePath，其尾巴還是有斜線的
    	        	//final String depFilePath = fileName;	//欲部署的檔案在那裡，此時的relativePath，其尾巴還是有斜線的
    	        	String sourceFilePath = "";
    	        	if ( isMR ) {
    	        		apRepo = apMRrepo;
    	        		sourceFilePath = wid.querySourceSVN(subsysId, modId).getS1()+"/"+relativePath+fileName;
    	        	} else {
    	        		apRepo = apOLrepo;
    	        		sourceFilePath = wid.querySourceSVN(subsysId, modId).getS2()+"/"+relativePath+fileName;
    	        	}
    	        	//在SVN CM OL 的repo中，將相對路徑的夾都建立出來
    	        	if ( relativePath.lastIndexOf("/") == relativePath.length()-1 && relativePath.length() !=0 ) {
    	        		relativePath = relativePath.substring(0, relativePath.length()-1);
    	        	}
    	        	final String[] arrRP = relativePath.split("/");
    	        	String currentPath = modId;
    	        	System.out.println("處理中的檔案："+depFilePath+",階層為"+arrRP.length);
    	        	
    	        	for( int i=0; i<arrRP.length;i++ ) {
    	        		currentPath += "/"+arrRP[i];
    	        		try {	//若能夠打開該路徑的資料夾，便是該夾存在，否則便進入catch來創建該資料夾
    	        			System.out.println("嘗試新增："+currentPath);
    		        		editor.addDir(arrRP[i],null,-1);
    		        	} catch ( Exception e) {
    		        		System.out.println("無法新增，嘗試打開"+currentPath);
    		        		//editor.openDir(arrRP[i],-1);
    		        	}
    	        		
    	        	}
    	        	//editor.openDir(relativePath,-1);
    	        	
    	        	try {
    	        		System.out.println("嘗試新增檔案"+fileName);
    	        		editor.addFile( depFilePath,null,-1);
    		        } catch(Exception e) {
    		        	System.out.println("無法新增改成開起");
    		        	editor.openFile( depFilePath,-1);
    		        }
    		        
    	        	apRepo.getFile( sourceFilePath,fileVer, fileProperties, baos);
    		        input  = new ByteArrayInputStream( baos.toByteArray() );
    		        
    	    		editor.applyTextDelta( depFilePath, null ); 
    	    		String baseChecksum = deltaGenerator.sendDelta( depFilePath, input, editor, true);
    	    	    editor.textDeltaEnd( depFilePath );
    	    	    editor.closeFile( depFilePath, baseChecksum );
    	    	    //editor.closeDir();
    	        }
    	        editor.closeDir();			//關閉 modId
    	        info =  editor.closeEdit();			//本次提交結束
            }
            
            //寫回 SVN CM的版次
    	    final long cmOLrepoVer = info.getNewRevision();
    	    System.out.println("產生的版次是"+cmOLrepoVer);
        } catch(Exception e) {
        	e.printStackTrace();
        } finally {
        	try {
				if ( baos !=null ) {baos.close();}
				if ( input !=null ) {input.close();}
				if ( rs !=null ) {rs.close();}
				if ( rs2 !=null ) {rs2.close();}
				if ( ps !=null ) {ps.close();}
				if ( ps2 !=null ) {ps2.close();}
				if ( conn !=null ) {conn.close();}
				if ( cmOLrepo != null ) { cmOLrepo.closeSession(); }
				if ( cmOLrepoCHK != null ) { cmOLrepoCHK.closeSession(); }
				if ( apMRrepo != null ) { apMRrepo.closeSession(); }
				if ( apOLrepo != null ) { apOLrepo.closeSession(); }
				if ( apRepo != null ) { apRepo.closeSession(); }
			} catch (Exception e) {
				e.printStackTrace();
			}
        }
	}

}
